<?php
/**
 * Minhlog Domain_Mapper 数据映射抽象类
 *
 * LICENSE
 *
 * This source file is subject to the new BSD license that is bundled
 * with this package in the file LICENSE.txt.
 *
 * @category   Domain
 * @package    Domain_DataMapper
 * @copyright  Copyright (c) 2009-2010 Minh.Shu@gmail.com
 * @license    New BSD License
 * @author     Minh.Shu
 * @version    $Id: Abstract.php 2 2010-01-17 13:49:08Z Minh.Shu $
 *
 */

abstract class Domain_DataMapper_Abstract
{
    /**
     * @var array 数据映射关系
     */
    protected $_dataMapper = array();

    /**
     * @var object 领域实体对象
     */
    protected $_entity = null;

    /**
     * @var object 数据库表对象
     */
    protected $_table = null;

    /**
     * @var string 数据库表名
     */
    protected $_tableClassName = '';

    /**
     * 设置数据映射
     * @param array $dataMapper
     * @return object
     */
    public function setDataMapper(array $dataMapper)
    {
        $this->_dataMapper = $dataMapper;
        return $this;
    }

    /**
     * 获取数据映射
     * @return object
     */
    public function getDataMapper()
    {
        if (null !== $this->_dataMapper) {
            throw new Exception (get_class($this) . '数据映射类protected属性dataMapper未定义!');
        }
        return $this->_dataMapper;
    }

    /**
     * 设置领域实体实例
     * @param Domain_Entity_Abstract $entity
     * @return object
     */
    public function setEntity(Domain_Entity_Abstract $entity)
    {
        $this->_entity = $entity;
        return $this;
    }

    /**
     * 获取领域实体实例
     * @return object
     */
    public function getEntity()
    {
        if (null === $this->_entity) {
            throw new Exception ('领域实体对象不存在!');
        }
        return clone $this->_entity;
    }

    /**
     * 创建数据表对象实例
     * @param string $table
     * @return object
     */
    public function setTable($table)
    {
        if (is_string($table) && class_exists($table)) {
            $this->_table = new $table();
        } else {
            throw new Exception(get_class($this) . '数据映射类protected属性tableClassName未定义!');
        }
        return $this;
    }

    /**
     * 获取数据表对象实例
     * @return object
     */
    public function getTable()
    {
        if (null === $this->_table) {
            $this->setTable($this->_tableClassName);
        }
        return $this->_table;
    }

    /**
     * 设置模型数据映射
     * @param Zend_Db_Table_Row $row
     * @return object|void
     */
    public function mapper(Zend_Db_Table_Row $row)
    {
        $entity = $this->getEntity();
        if(isset($this->_dataMapper)){
            foreach ($this->_dataMapper as $property => $tableField) {
                $entity->$property = $row->$tableField;
            }
            return $entity;
        } else {
            throw new Exception(get_class($this) . '数据映射类protected属性dataMapper未定义!');
        }
    }

    /**
     * 根据主键查询结果
     * @param integer $primary
     * @return object|void
     */
    public function findByPrimaryId($primary)
    {
        $result = $this->getTable()->find($primary);

        if($result->count()) {
            $row = $result->current();
            return $this->mapper($row);
        } else {
            return;
        }
    }

    /**
     * 根据$select语句查询结果
     * @param Zend_Db_Table_Select $select
     */
    public function findAll($select)
    {
        if (($select instanceof Zend_Db_Table_Select)) {
            $resultSet = $this->getTable()->fetchAll($select);

            if ($resultSet->count()) {
                $entries = array();
                foreach ($resultSet as $value) {
                    $entry = $this->mapper($value);
                    $entries[] = $entry;
                }
                return $entries;
            } else {
                return null;
            }
        }
    }

    /**
     * 保存信息公共方法
     * @param array $data
     * @param integer $primaryId
     * @return
     */
    public function save($data, $primaryId = 0)
    {
        $db = $this->getTable()->getAdapter();
        if($primaryId > 0){
            $idKeys = $this->getTable()->info(Zend_Db_Table::PRIMARY);
            $where = "{$idKeys[1]} = ".$primaryId;
            $update = $this->getTable()->update($data, $where);
            return $primaryId;
        }else{
            $insert = $this->getTable()->insert($data);
            return $db->lastInsertId();
        }
    }

    /**
     * 根据主键删除数据公共方法
     * @param integer $primaryId
     * @return
     */
    public function delete($primaryId)
    {
        if($primaryId > 0)
        {
            $idKeys = $this->getTable()->info(Zend_Db_Table::PRIMARY);
            $where = "{$idKeys[1]} = ".$primaryId;
            $delete = $this->getTable()->delete($where);
            return $primaryId;
        }else{
            return false;
        }
    }

    /**
     * 根据主键删除依赖关联数据公共方法
     * @param integer $primaryId
     * @return
     */
    public function deleteDependent($primaryId)
    {
        if($primaryId > 0)
        {
            $deleteRow = $this->getTable()->find($primaryId)->current();
            if($deleteRow) $deleteRow->delete();
        }else{
            return false;
        }
    }

    /**
     * 根据where条件删除数据公共方法
     * @param string $where
     * @return
     */
    public function deleteWhere($where)
    {
        return $this->getTable()->delete($where);
    }
}